#!/bin/bash
###############################################################################
#       脚本名称: test_utils.sh
#       功能描述: Utils模块统一API接口(utils.sh)单元测试。
#       作者: 林再来
#       日期: 2025-10-20
#       版本: 1.0
#       功能:
#           1、测试utils.sh统一API接口的所有核心功能
#           2、验证模块加载、依赖管理、错误处理等功能
#           3、确保统一接口的正确性和稳定性
###############################################################################

# 切换到脚本目录
cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1

# 加载测试框架
source ../test_framework.sh

# 加载被测模块
source ../../../scripts/utils/utils.sh

# 创建临时测试目录
TEST_DIR=$(create_test_dir)

###############################################################################
# 测试用例
###############################################################################

# 测试: utils模块初始化
test_utils_init() {
    # 检查模块是否已加载
    if [[ -n "${utils_sh_loaded:-}" ]]; then
        echo "✓ utils.sh模块已加载"
    else
        echo "✗ utils.sh模块未加载"
        return 1
    fi
}

# 测试: 列出所有模块
test_utils_list_modules() {
    local output=$(utils_list_modules 2>&1)
    assert_contains "$output" "datetime" "应该包含datetime模块"
    assert_contains "$output" "file" "应该包含file模块"
    assert_contains "$output" "email" "应该包含email模块"
    assert_contains "$output" "validate" "应该包含validate模块"
    assert_contains "$output" "jq" "应该包含jq模块"
    assert_contains "$output" "yq" "应该包含yq模块"
    assert_contains "$output" "character" "应该包含character模块"
    assert_contains "$output" "number" "应该包含number模块"
}

# 测试: 检查模块加载状态
test_utils_is_loaded() {
    # 初始状态应该没有加载任何模块
    assert_false "初始状态不应该有模块加载" "utils_is_loaded datetime"
    
    # 调用一个datetime函数，应该自动加载模块
    utils datetime format "2025-01-01" "%Y-%m-%d" >/dev/null 2>&1
    
    # 现在应该已加载datetime模块
    assert_true "调用后应该已加载datetime模块" "utils_is_loaded datetime"
}

# 测试: 获取已加载模块列表
test_utils_loaded_modules() {
    # 清空已加载模块
    unset _utils_loaded_modules
    declare -A _utils_loaded_modules
    
    local output=$(utils_loaded_modules 2>&1)
    assert_contains "$output" "当前没有加载任何模块" "应该显示没有加载模块"
    
    # 加载一个模块
    utils datetime format "2025-01-01" "%Y-%m-%d" >/dev/null 2>&1
    
    local output=$(utils_loaded_modules 2>&1)
    assert_contains "$output" "datetime" "应该显示已加载datetime模块"
}

# 测试: 统一接口调用 - datetime模块
test_utils_datetime_interface() {
    local result=$(utils datetime format "2025-01-01" "%Y-%m-%d" 2>/dev/null)
    assert_equals "2025-01-01" "$result" "datetime格式化应该正确"
    
    local result=$(utils datetime now "%Y-%m-%d" 2>/dev/null)
    assert_not_empty "$result" "datetime now应该返回当前日期"
}

# 测试: 统一接口调用 - character模块
test_utils_character_interface() {
    local result=$(utils character to_upper "hello" 2>/dev/null)
    assert_equals "HELLO" "$result" "character转大写应该正确"
    
    local result=$(utils character to_lower "WORLD" 2>/dev/null)
    assert_equals "world" "$result" "character转小写应该正确"
    
    local result=$(utils character reverse "abc" 2>/dev/null)
    assert_equals "cba" "$result" "character反转应该正确"
}

# 测试: 统一接口调用 - number模块
test_utils_number_interface() {
    local result=$(utils number add "10" "5" 2>/dev/null)
    assert_equals "15" "$result" "number加法应该正确"
    
    local result=$(utils number multiply "3" "4" 2>/dev/null)
    assert_equals "12" "$result" "number乘法应该正确"
    
    local result=$(utils number is_positive "5" 2>/dev/null)
    assert_true "number正数检查应该正确" "[[ $? -eq 0 ]]"
}

# 测试: 统一接口调用 - validate模块
test_utils_validate_interface() {
    utils validate required "test" "参数名" 2>/dev/null
    assert_true "validate必填检查应该通过" "[[ $? -eq 0 ]]"
    
    utils validate required "" "参数名" 2>/dev/null
    assert_false "validate空值检查应该失败" "[[ $? -eq 0 ]]"
}

# 测试: 错误处理 - 未知模块
test_utils_unknown_module() {
    local output=$(utils unknown_module test_function 2>&1)
    assert_contains "$output" "未知的工具模块" "应该显示未知模块错误"
}

# 测试: 错误处理 - 缺少参数
test_utils_missing_params() {
    local output=$(utils 2>&1)
    assert_contains "$output" "缺少模块类别参数" "应该显示缺少参数错误"
    
    local output=$(utils datetime 2>&1)
    assert_contains "$output" "缺少函数名参数" "应该显示缺少函数名错误"
}

# 测试: 错误处理 - 未知函数
test_utils_unknown_function() {
    local output=$(utils datetime unknown_function 2>&1)
    assert_contains "$output" "函数不存在" "应该显示函数不存在错误"
}

# 测试: 便捷函数
test_utils_convenience_functions() {
    local result=$(utils_date_format "2025-01-01" "%Y-%m-%d" 2>/dev/null)
    assert_equals "2025-01-01" "$result" "便捷日期格式化应该正确"
    
    local result=$(utils_validate "test" "参数名" 2>/dev/null)
    assert_true "便捷参数验证应该通过" "[[ $? -eq 0 ]]"
}

# 测试: 调试模式控制
test_utils_debug_mode() {
    local output=$(utils_set_debug true 2>&1)
    assert_contains "$output" "调试模式已启用" "应该显示调试模式启用"
    
    local output=$(utils_set_debug false 2>&1)
    assert_contains "$output" "调试模式已禁用" "应该显示调试模式禁用"
}

# 测试: 版本信息
test_utils_version() {
    local output=$(utils_version 2>&1)
    assert_contains "$output" "Utils模块统一API接口" "应该显示模块名称"
    assert_contains "$output" "版本: 1.0" "应该显示版本号"
    assert_contains "$output" "支持的模块" "应该显示支持的模块"
}

# 测试: 帮助信息
test_utils_help() {
    local output=$(utils_help 2>&1)
    assert_contains "$output" "Utils模块统一API接口" "应该显示帮助标题"
    assert_contains "$output" "基本用法" "应该显示基本用法"
    assert_contains "$output" "可用类别" "应该显示可用类别"
    assert_contains "$output" "使用示例" "应该显示使用示例"
}

# 测试: 模块依赖处理
test_utils_dependencies() {
    # email模块依赖validate和file模块
    utils email send "test@example.com" "test" "test" 2>/dev/null
    
    # 检查依赖模块是否已加载
    assert_true "email模块应该已加载" "utils_is_loaded email"
    # 注意：由于email模块的依赖处理，validate和file模块也应该被加载
}

# 测试: 模块列表函数
test_utils_list_functions() {
    local output=$(utils_list_functions datetime 2>&1)
    assert_contains "$output" "format" "应该包含format函数"
    assert_contains "$output" "now" "应该包含now函数"
    
    local output=$(utils_list_functions character 2>&1)
    assert_contains "$output" "to_upper" "应该包含to_upper函数"
    assert_contains "$output" "to_lower" "应该包含to_lower函数"
}

# 测试: 错误处理 - 无效模块类别
test_utils_invalid_category() {
    local output=$(utils_list_functions invalid_category 2>&1)
    assert_contains "$output" "未知的工具模块" "应该显示未知模块错误"
}

# 测试: 脚本直接运行
test_utils_script_direct_run() {
    # 测试脚本直接运行时的帮助功能
    local script_path="../../../scripts/utils/utils.sh"
    
    local output=$(bash "$script_path" help 2>&1)
    assert_contains "$output" "Utils模块统一API接口" "直接运行应该显示帮助"
    
    local output=$(bash "$script_path" version 2>&1)
    assert_contains "$output" "版本: 1.0" "直接运行应该显示版本"
    
    local output=$(bash "$script_path" list 2>&1)
    assert_contains "$output" "可用的工具模块" "直接运行应该显示模块列表"
}

###############################################################################
# 运行测试
###############################################################################

echo "========================================"
echo "测试套件: Utils模块统一API接口 (utils.sh)"
echo "========================================"

# 运行所有测试
run_test "utils模块初始化" test_utils_init
run_test "列出所有模块" test_utils_list_modules
run_test "检查模块加载状态" test_utils_is_loaded
run_test "获取已加载模块列表" test_utils_loaded_modules
run_test "统一接口调用 - datetime模块" test_utils_datetime_interface
run_test "统一接口调用 - character模块" test_utils_character_interface
run_test "统一接口调用 - number模块" test_utils_number_interface
run_test "统一接口调用 - validate模块" test_utils_validate_interface
run_test "错误处理 - 未知模块" test_utils_unknown_module
run_test "错误处理 - 缺少参数" test_utils_missing_params
run_test "错误处理 - 未知函数" test_utils_unknown_function
run_test "便捷函数" test_utils_convenience_functions
run_test "调试模式控制" test_utils_debug_mode
run_test "版本信息" test_utils_version
run_test "帮助信息" test_utils_help
run_test "模块依赖处理" test_utils_dependencies
run_test "模块列表函数" test_utils_list_functions
run_test "错误处理 - 无效模块类别" test_utils_invalid_category
run_test "脚本直接运行" test_utils_script_direct_run

echo "----------------------------------------"
echo "测试套件 [Utils模块统一API接口 (utils.sh)] 完成"
echo "----------------------------------------"
